package hdd.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.interceptor.TransactionInterceptor;

import javax.sql.DataSource;
import java.io.IOException;
import java.util.Properties;

@Configuration
@EnableTransactionManagement
@PropertySource( {"classpath:jdbc.properties"} )
public class DataSourceConfig   implements EnvironmentAware {
    private Environment environment;

    @Bean
    public DruidDataSource druidDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource(  );
        druidDataSource.setDriverClassName( environment.getProperty( "jdbc.driverClassName" ) );
        druidDataSource.setUrl( environment.getProperty( "jdbc.url" ) );
        druidDataSource.setUsername( environment.getProperty( "jdbc.username" ) );
        druidDataSource.setPassword( environment.getProperty( "jdbc.password" ) );

        druidDataSource.setMinIdle( environment.getProperty( "jdbc.minIdle",Integer.class ) );
        druidDataSource.setInitialSize( environment.getProperty( "jdbc.initialSize",Integer.class ) );
        druidDataSource.setMaxActive( environment.getProperty( "jdbc.maxActive",Integer.class ) );
        return druidDataSource;
    }


    @Bean("sqlSessionFactoryBean")
    public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) throws IOException {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource( dataSource );
        sqlSessionFactoryBean.setTypeAliasesPackage( "POJO" );
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:/mybatis/mapper/*.xml"));
        return sqlSessionFactoryBean;
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName( "sqlSessionFactoryBean" );
        mapperScannerConfigurer.setBasePackage( "service" );
        return mapperScannerConfigurer;
    }


    @Bean
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory){
        SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate( sqlSessionFactory );
        return  sqlSessionTemplate;
    }


    //========================声明式事务配置=========================
    //事务管理器（声明式的事务）
    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager(DataSource dataSource) {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource( dataSource );
        return dataSourceTransactionManager;
    }

    //事务管理   使用拦截器
    @Bean
    public TransactionInterceptor transactionInterceptor(DataSourceTransactionManager dataSourceTransactionManager) {
        TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
        transactionInterceptor.setTransactionManager( dataSourceTransactionManager );
        Properties properties = new Properties();
        properties.setProperty( "*", "readOnly" );
        properties.setProperty( "add*", "PROPAGATION_REQUIRED,-Exception" );
        properties.setProperty( "save*", "PROPAGATION_REQUIRED,-Exception" );
        properties.setProperty( "insert*", "PROPAGATION_REQUIRED,-Exception" );
        properties.setProperty( "modify*", "PROPAGATION_REQUIRED,-Exception" );
        properties.setProperty( "update*", "PROPAGATION_REQUIRED,-Exception" );
        properties.setProperty( "delete*", "PROPAGATION_REQUIRED,-Exception" );
        properties.setProperty( "remove*", "PROPAGATION_REQUIRED,-Exception" );
        properties.setProperty( "query*", "PROPAGATION_REQUIRED,-Exception" );
        properties.setProperty( "select*", "PROPAGATION_REQUIRED,-Exception" );
        properties.setProperty( "load*", "PROPAGATION_REQUIRED,-Exception" );
        transactionInterceptor.setTransactionAttributes( properties );
        return transactionInterceptor;
    }

    //创建proxy
    @Bean
    public BeanNameAutoProxyCreator beanNameAutoProxyCreator() {
        BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
        beanNameAutoProxyCreator.setBeanNames( "*Mapper" );//定义为哪些bena生成代理
        beanNameAutoProxyCreator.setInterceptorNames( "transactionInterceptor" );//设置拦截器的名称（可设置多个）
        return beanNameAutoProxyCreator;
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment = environment;
    }
}
